home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
IRIX 6.2 Applications 1996 May
/
SGI IRIX 6.2 Applications 1996 May.iso
/
dist
/
impr_dev.idb
/
usr
/
impressario
/
src
/
libspool
/
SLBsd.c.z
/
SLBsd.c
Wrap
C/C++ Source or Header
|
1996-05-06
|
29KB
|
1,039 lines
/**************************************************************************
* *
* Copyright (c) 1991 Silicon Graphics, Inc. *
* All Rights Reserved *
* *
* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SGI *
* *
* The copyright notice above does not evidence any actual of intended *
* publication of such source code, and is an unpublished work by Silicon *
* Graphics, Inc. This material contains CONFIDENTIAL INFORMATION that is *
* the property of Silicon Graphics, Inc. Any use, duplication or *
* disclosure not specifically authorized by Silicon Graphics is strictly *
* prohibited. *
* *
* RESTRICTED RIGHTS LEGEND: *
* *
* Use, duplication or disclosure by the Government is subject to *
* restrictions as set forth in subdivision (c)(1)(ii) of the Rights in *
* Technical Data and Computer Software clause at DFARS 52.227-7013, *
* and/or in similar or successor clauses in the FAR, DOD or NASA FAR *
* Supplement. Unpublished - rights reserved under the Copyright Laws of *
* the United States. Contractor is SILICON GRAPHICS, INC., 2011 N. *
* Shoreline Blvd., Mountain View, CA 94039-7311 *
**************************************************************************
*
* File: SLBsd.c
*
* Description: This file contains the BSD spooling system specific
* handling functions.
*
**************************************************************************/
#ident "$Revision: 1.7 $"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <pwd.h>
#include <sys/types.h>
#include <signal.h>
#include <errno.h>
#include "spoolI.h"
/* Printcap file capability keyword structure */
typedef struct {
char *key; /* Keyword in printcap file */
char **pvar; /* Pointer to strinct var in printer struct */
} KeywordStruct;
static KeywordStruct keywords[] = {
{ "lp", NULL },
{ "ty", NULL },
{ "rm", NULL },
{ "rp", NULL },
};
static int num_keywords = sizeof(keywords) / sizeof(KeywordStruct);
/* BSD spooling directories and files */
static char *printcap_file = "/etc/printcap";
/* Print queue */
static SLQueueStruct *bsd_queue; /* Job queue */
static int num_bsd_queue; /* Number of jobs in queue */
/* Local functions */
static char *get_entry(FILE*);
static void parse_capabilities(char*, SLPrinterStruct*);
static int def_check(char*, char*);
static void parse_queue(SLQueueStruct*, char*);
/**************************************************************************
*
* Function: _SLBsdFindSpooler
*
* Description: Determines whether the BSD print scheduler is running.
*
* Parameters: none
*
* Return: 1 if the scheduler is running, 0 otherwise.
*
**************************************************************************/
int _SLBsdFindSpooler(void)
{
FILE *fptr;
pid_t pid;
/*
* Try to open lpd.lock for reading. If we cannot open the file
* assume that the scheduler is running unless we got the file does
* not exit error.
*
* Note that here we use high level file I/O because the pid is
* written as text into the lock file as opposed to System V which
* writes the pid in binary.
*/
if ((fptr = fopen(SL_LPD_LOCK, "r")) == NULL) {
if (errno == ENOENT)
return 0;
return 1;
}
/*
* When the scheduler starts it puts its pid in the lock file.
* Read this pid and use kill to determine if the process is
* around, thereby indicating that the scheduler is running. The
* only danger here is that the scheduler is not running and its
* pid has been reused. However, this case is not very likely.
*/
if (fscanf(fptr, "%ld", &pid) != 1) {
(void)fclose(fptr);
return 0;
}
if (kill(pid, 0) < 0) {
if (errno == ESRCH) { /* Indicates invalid pid */
(void)fclose(fptr);
return 0;
}
}
(void)fclose(fptr);
return 1;
}
/**************************************************************************
*
* Function: _SLBsdGetPrinterList
*
* Description: Provides a list of the printers recognized by the
* BSD spooling system. Any old pointers to the list become invalid
* when this function is again called. Users must make copy of the
* list in order to preserve old lists.
*
* Parameters:
* printersp (O) - set to a list of available printers
* num_printersp (O) - number of available printers in list
*
* Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
* error has occurred.
*
**************************************************************************/
int _SLBsdGetPrinterList(SLPrinterStruct *printersp[], int *num_printersp)
{
FILE *fptr;
char *eptr, *sptr, *formal_name;
char *penv, *loc;
int def;
SLPrinterStruct info;
static SLPrinterStruct *bsd_printers = NULL;
static int num_bsd_printers = 0;
/*
* Clear out and initialize the list of BSD printers
*/
_SLInitPlist(&bsd_printers, &num_bsd_printers);
/*
* Get the PRINTER environment variable setting, if any
*/
penv = getenv("PRINTER");
if (penv && *penv == '\0')
penv = NULL;
/*
* Attempt to open and read the printcap file
*/
if ((fptr = fopen(printcap_file, "r")) != NULL) {
/*
* First get a complete printcap entry
*/
while ((eptr = get_entry(fptr)) != NULL) {
/*
* Parse the capabilities part of the entry
* entry the appropriate fields of the printer_caps
* structure.
*/
parse_capabilities(eptr, &info);
/*
* Now for each printer name add a printer to the list,
* copy the printer_caps structure to the new printer
* and fill in the printer name fields. Note that the
* formal name is assumed to be the last name. Also
* note that if 'lp' or the printer name specified by the
* PRINTER environment variable is one of the names, then all
* the printer names on the line are marked as default
* printers.
*/
(void)strtok_r(eptr, ":", &loc);
def = def_check(eptr, (penv) ? penv: "lp");
if ((sptr = strrchr(eptr, '|')) == NULL)
formal_name = eptr;
else
formal_name = sptr + 1;
while ((sptr = strtok_r(eptr, "|", &loc)) != NULL) {
eptr = NULL;
info.local_name = strdup(sptr);
info.formal_name = strdup(formal_name);
info.is_def = def;
info.is_class = 0;
_SLAddPrinter(&info, &bsd_printers, &num_bsd_printers);
}
}
(void)fclose(fptr);
}
*num_printersp = num_bsd_printers;
*printersp = bsd_printers;
return SL_NOERROR;
}
/**************************************************************************
*
* Function: _SLBsdGetPrinterInfo
*
* Description: Provides detailed information about the specified BSD
* printer. Each time this function is called the old contents of
* the internal info structure become invalid. If the user wishes to
* preserve the old info, a copy must be made before calling this
* function.
*
* Parameters:
* printer (I) - printer whose info is wanted. Public function sets
* this to default printer name if user specified it
* as NULL.
* printer_infop (O) - set to a printer information structure
* filled with information about the printer. Set
* to NULL if the specified printer does not exist.
*
* Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
* error has occurred. It is considered an error specifying a printer
* that is not available to the spooler.
*
**************************************************************************/
int _SLBsdGetPrinterInfo(const char *printer, SLPrinterStruct **printer_infop)
{
FILE *fptr;
char *eptr, *sptr, *formal_name;
char *penv, *loc;
char dup_eptr[SL_BUF_PRINTCAP];
int def, found = 0;
static SLPrinterStruct pinfo;
/*
* First clear any storage that may have been allocated for the struct
*/
_SLInitPentry(&pinfo);
/*
* Get the PRINTER environment variable setting, if any
*/
penv = getenv("PRINTER");
if (penv && *penv == '\0')
penv = NULL;
/*
* Attempt to open and read the printcap file
*/
if ((fptr = fopen(printcap_file, "r")) != NULL) {
/*
* First get a complete printcap entry
*/
while (!found && (eptr = get_entry(fptr)) != NULL) {
/*
* Save a copy of the entry for later parsing of
* capabilities if this is the desired printer
*/
(void)strcpy(dup_eptr, eptr);
/*
* Now hunt for the desired printer.
*/
(void)strtok_r(eptr, ":", &loc);
def = def_check(eptr, (penv) ? penv: "lp");
if ((sptr = strrchr(eptr, '|')) == NULL)
formal_name = eptr;
else
formal_name = sptr + 1;
while ((sptr = strtok_r(eptr, "|", &loc)) != NULL) {
eptr = NULL;
if (!strcmp(printer, sptr)) {
parse_capabilities(dup_eptr, &pinfo);
pinfo.local_name = strdup(sptr);
pinfo.formal_name = strdup(formal_name);
pinfo.is_def = def;
pinfo.is_class = 0;
found = 1;
break;
}
}
}
(void)fclose(fptr);
}
if (!found)
RETURN_ERROR(SL_ERR_BAD_PRINTER_NAME);
*printer_infop = &pinfo;
return SL_NOERROR;
}
/**************************************************************************
*
* Function: _SLBsdGetDefPrinterName
*
* Description: Returns the default printer name recognized by the BSD
* spooling system.
*
* Parameters:
* pnamep (O) - default printer or NULL if none selected
*
* Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
* error has occurred.
*
**************************************************************************/
int _SLBsdGetDefPrinterName(char **pnamep)
{
FILE *fptr;
char *eptr, *loc;
static char *dname = "lp";
/*
* Get the PRINTER environment variable setting, if any
* otherwise parse the printcap for the default, 'lp', if any
*/
if ((*pnamep = getenv("PRINTER")) == NULL) {
if ((fptr = fopen(printcap_file, "r")) != NULL) {
while ((eptr = get_entry(fptr)) != NULL) {
(void)strtok_r(eptr, ":", &loc);
if (def_check(eptr, "lp")) {
*pnamep = dname;
break;
}
}
(void)fclose(fptr);
}
}
/*
* If no def printer make sure pointer is NULL and
* return error to the user
*/
if (*pnamep == NULL || *pnamep[0] == '\0') {
*pnamep = NULL;
RETURN_ERROR(SL_ERR_NO_DEF_PRINTER);
}
return SL_NOERROR;
}
/**************************************************************************
*
* Function: _SLBsdGetPrinterSettings
*
* Description: Reads the spooler and printer option settings.
*
* Currently, there are no tools which save BSD spooler or printer
* specific settings. This function returns the default settings.
*
* Parameters:
* printer (I) - printer whose settings are wanted.
* settingsp (O) - set to a printer settings structure
* filled with the currently saved printer settings.
* information about the printer.
*
* Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
* error has occurred.
*
**************************************************************************/
/* ARGSUSED */
int _SLBsdGetPrinterSettings(const char *printer,
SLSettingsStruct **settingsp)
{
static SLSettingsStruct settings;
/*
* Fill the settings structure with default values
* and return it.
*/
settings.copy = 1;
settings.mail = 0;
settings.title = NULL;
settings.options = NULL;
*settingsp = &settings;
return SL_NOERROR;
}
/**************************************************************************
*
* Function: _SLBsdSubmitJob
*
* Description: Submits a job for printing using the BSD spooler.
*
* Parameters:
* job_source (I) - union describing the print job source (eg.
* filename, fd, etc.)
* printer (I) - printer on which to print job. Public function
* fills this with the default printer if the
* user specified it as NULL.
* num_copies (I) - number of copies
* copy (I) - Copy flag. If 1 then file is copied to spooling dir. If
* 0 a link is created.
* mail (I) - Mail flag. If 1 then mail is sent on job print completion.
* If 0, no mail is sent.
* title (I) - title to appear on banner page.
* options (I) - string of spooling system/printer specific options.
* Set to NULL if none.
* job_idp (O) - print job ID
*
* Return: 0 if no error. -1 and SLerrno set if error.
*
**************************************************************************/
int _SLBsdSubmitJob(SLJobSourceUnion *job_source, const char *printer,
int num_copies, int copy, int mail,
const char *title, const char *options,
char **job_idp)
{
char cmd_buf[SL_BUFSIZ], buf[SL_BUFSIZ];
char *t_ptr;
char *b_ptr;
/*
* Start filling the command buffer with parameters. Start with
* the printing command and the destination printer name
*/
(void)sprintf(cmd_buf, "%s -P%s", SL_CMD_LPR, printer);
/* Number of copies */
if (num_copies > 1) {
(void)sprintf(buf, " -#%d", num_copies);
(void)strcat(cmd_buf, buf);
}
/* Don't copy file to spool dir */
if (!copy)
(void)strcat(cmd_buf, " -s");
/* Mail sent on completion */
if (mail)
(void)strcat(cmd_buf, " -m");
/* Banner page title -- handle a char at a time to handle case of
* characters that the shell will interpret
*/
if (title) {
for (t_ptr = (char *)title, b_ptr = buf; *t_ptr; t_ptr++) {
if ( !isalnum((int) *t_ptr) && !isspace((int) *t_ptr) ) {
*b_ptr++ = '\\'; /* Escape these */
}
*b_ptr++ = *t_ptr;
if ((b_ptr - buf) == SL_BUFSIZ-10) break; /* Stay in bounds */
}
*b_ptr = '\0';
(void)strcat(cmd_buf, " -J\"");
/* (void)sprintf(buf, " -J '%s'", title); */
(void)strcat(cmd_buf, buf);
(void)strcat(cmd_buf, "\"");
}
/* Printer/Spooler specific options */
if (options) {
(void)sprintf(buf, " %s", options);
(void)strcat(cmd_buf, buf);
}
/* Add the file(s) to print, if appropriate */
if (job_source->type == SL_JOB_FILENAME) {
(void)sprintf(buf, " %s", job_source->filename_job.filename);
(void)strcat(cmd_buf, buf);
}
/* Lastly add the sh output redirection */
(void)sprintf(buf, " %s", SL_SH_REDIRECT);
(void)strcat(cmd_buf, buf);
/*
* Issue the command. Note that BSD does not return a
* job ID so we send back NULL.
*/
if (_SLExec(job_source, cmd_buf, SL_FALSE, NULL) != 0) {
RETURN_ERROR(SL_ERR_SPOOLER_ERROR);
}
*job_idp = NULL;
return SL_NOERROR;
}
/**************************************************************************
*
* Function: _SLBsdCancelJob
*
* Description: Sends a cancel print job request to the BSD spooling
* system. Note that there is no confirmation that a print job has
* actually been canceled.
*
* Parameters:
* job_id (I) - print job ID(s) of the job(s) that are to be canceled.
* printer (I) - printer on which the job resides. If NULL the
* current default printer is used.
*
* Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
* error has occurred.
*
**************************************************************************/
int _SLBsdCancelJob(const char *job_id, const char *printer)
{
char cmd_buf[SL_BUFSIZ];
char *def_printer;
int rv;
/*
* If no printer specified, use default.
* If printer specified sanity check the name.
*/
if (!printer) {
if ((rv = _SLBsdGetDefPrinterName(&def_printer)) < 0)
return rv;
printer = def_printer;
} else if (_SLIsEmpty(printer))
RETURN_ERROR(SL_ERR_BAD_PRINTER_NAME);
/*
* Fill the command buffer with parameters
* lprm + Printer + Job ID(s) + sh output direction
*/
(void)sprintf(cmd_buf, "%s -P%s %s %s",
SL_CMD_LPRM,
printer,
job_id,
SL_SH_REDIRECT);
/*
* Issue the command
*/
if (_SLExec(NULL, cmd_buf, SL_FALSE, NULL) != 0)
RETURN_ERROR(SL_ERR_SPOOLER_ERROR);
return SL_NOERROR;
}
/**************************************************************************
*
* Function: _SLBsdGetSpoolerState
*
* Description: Returns the state of the specified spooling function for
* the BSD spooling system.
*
* Parameters:
* printer (I) - printer whose spooler state to query.
* function (I) - spooling function whose state to query (one of
* SL_PRINTING or SL_QUEUEING).
* statep (O) - state of the spooling function (one of SL_ENABLED or
* SL_DISABLED).
*
* Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
* error has occurred.
*
**************************************************************************/
int _SLBsdGetSpoolerState(const char *printer, int function, int *statep)
{
char cmd_buf[SL_BUFSIZ];
/*
* Fill the command buffer with parameters
* lpc + status + printer + sh output redirection
*/
(void)sprintf(cmd_buf, "%s status %s %s",
SL_CMD_LPC,
printer,
SL_SH_REDIRECT);
/*
* Issue the command
*/
if (_SLExec(NULL, cmd_buf, SL_FALSE, NULL) != 0)
RETURN_ERROR(SL_ERR_SPOOLER_ERROR);
/*
* Parse out the state information
*/
if (_SLspooler_nout >= 3) {
if (function == SL_PRINTING) {
if (strstr(_SLspooler_out_buf[2], "disabled") != NULL)
*statep = SL_DISABLED;
else if (strstr(_SLspooler_out_buf[2], "enabled") != NULL)
*statep = SL_ENABLED;
else {
_SLspooler_exit = 1; /* Stupid System V returned 0 */
RETURN_ERROR(SL_ERR_SPOOLER_ERROR);
}
} else { /* Queueing */
if (strstr(_SLspooler_out_buf[1], "disabled") != NULL)
*statep = SL_DISABLED;
else if (strstr(_SLspooler_out_buf[1], "enabled") != NULL)
*statep = SL_ENABLED;
else {
_SLspooler_exit = 1; /* Stupid System V returned 0 */
RETURN_ERROR(SL_ERR_SPOOLER_ERROR);
}
}
} else
RETURN_ERROR(SL_ERR_NO_STATE);
return SL_NOERROR;
}
/**************************************************************************
*
* Function: _SLBsdSetSpoolerState
*
* Description: Sets the state of the specified spooling function for the
* BSD spooling system.
*
* Parameters:
* printer (I) - printer whose spooler state to set.
* function (I) - spooling function whose state to set (one of
* SL_PRINTING or SL_QUEUEING).
* state (I) - state to set for the spooling function (one of
* SL_ENABLED or SL_DISABLED).
*
* Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
* error has occurred.
*
**************************************************************************/
int _SLBsdSetSpoolerState(const char *printer, int function, int state)
{
char cmd_buf[SL_BUFSIZ], buf[SL_BUFSIZ];
/*
* Make sure that we are root since all spooler state
* operations are priveleged in BSD. Note that I check uid
* and not euid. This is because the underlying BSD command
* check uid not euid. I must do what BSD does or you will
* pass my test and fail theirs.
*/
if (getuid() != 0)
RETURN_ERROR(SL_ERR_PRIVILEGE);
/*
* Start filling the command buffer with parameters
*/
(void)sprintf(cmd_buf, "%s ", SL_CMD_LPC);
if (function == SL_PRINTING) {
(void)strcat(cmd_buf, (state == SL_ENABLED) ? "start": "stop");
} else { /* Queueing */
(void)strcat(cmd_buf, (state == SL_ENABLED) ? "enable": "disable");
}
/* Add the printer and sh output redirection */
(void)sprintf(buf, " %s %s", printer, SL_SH_REDIRECT);
(void)strcat(cmd_buf, buf);
/*
* Issue the command
*/
if (_SLExec(NULL, cmd_buf, SL_FALSE, NULL) != 0)
RETURN_ERROR(SL_ERR_SPOOLER_ERROR);
/*
* BSD has a problem with reporting a non-zero exit status for
* errors such as unknown printers. The heuristic here is to check
* for the phrase "unkown printer" in the rist line of the return
* string.
*/
if (_SLspooler_nout) {
if (strstr(*_SLspooler_out_buf, "unknown printer")) {
_SLspooler_exit = 1; /* Stupid BSD returned 0 */
RETURN_ERROR(SL_ERR_SPOOLER_ERROR);
}
}
return SL_NOERROR;
}
/**************************************************************************
*
* Function: _SLBsdGetQueue
*
* Description: Returns the job queue for the specified printer under
* the BSD spooling system.
*
* Parameters:
* printer_info (I) - printer structure. Cannot be NULL.
* queue_type (I) - not used for the BSD spooler.
* queuep (O) - print queue entries.
* num_queuep (O) - number of entries in the queue.
*
* Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
* error has occurred.
*
**************************************************************************/
/* ARGSUSED */
int _SLBsdGetQueue(const SLPrinterStruct *printer_info, int queue_type,
SLQueueStruct *queuep[], int *num_queuep)
{
char cmd_buf[SL_BUFSIZ];
int i;
SLQueueStruct *qentry;
/*
* Clear out and initialize the BSD queue
*/
_SLInitQueue(&bsd_queue, &num_bsd_queue);
/*
* Form the queue command and issue it
*/
(void)sprintf(cmd_buf, "%s -P%s %s",
SL_CMD_LPQ,
printer_info->local_name,
SL_SH_REDIRECT);
if (_SLExec(NULL, cmd_buf, SL_FALSE, NULL) != 0)
RETURN_ERROR(SL_ERR_SPOOLER_ERROR);
/*
* Now parse the output to form the queue. We look for the
* keyword '1st' to mark the start of the queue info
*/
for (i = 0; i < _SLspooler_nout; i++) {
if (strstr(_SLspooler_out_buf[i], "1st")) {
break;
}
}
for (; i < _SLspooler_nout; i++) {
if (_SLIsEmpty(_SLspooler_out_buf[i]))
break;
qentry = _SLAddQueue(&bsd_queue, &num_bsd_queue);
parse_queue(qentry, _SLspooler_out_buf[i]);
qentry->is_local = 1; /* Entries can be considered local on BSD */
}
*num_queuep = num_bsd_queue;
*queuep = bsd_queue;
return SL_NOERROR;
}
#ifdef _SL_FASTPATH
/**************************************************************************
*
* Function: _SLBsdSupportsFastJob
*
* Description:
* Find out whether a printer supports fast print jobs
* For now, fast print jobs are not supported on BSD spoolers.
*
* Parameters:
* printer printer to find out if supports fast jobs
*
* Return: non-zero if fast job supported, 0 otherwise
*
**************************************************************************/
/* ARGSUSED */
int _SLBsdSupportsFastJob(const char *printer)
{
return SL_FALSE;
}
#endif /* _SL_FASTPATH */
/**************************************************************************
*
* Function: _SLBsdFindUserName
*
* Description: Determines the user name in the same manner as the BSD
* spooling system.
*
* Parameters: none
*
* Return: Pointer to user name. The storage for username is static and
* the returned value should be copied if it is not going to be
* used immediately after the call.
*
**************************************************************************/
char* _SLBsdFindUserName(void)
{
static char *unknown = "Unknown";
struct passwd *pw;
return ((pw = getpwuid(getuid())) == NULL) ? unknown: pw->pw_name;
}
/*
==========================================================================
LOCAL FUNCTIONS
==========================================================================
*/
/**************************************************************************
*
* Function: get_entry
*
* Description: Returns a pointer to a printcap file entry. The file
* is searched for the next printcap entry. Comments and blank lines
* are skipped. Coninuation characters are stripped out and all
* lines comprising the entry are reassembled into one line.
*
* Per BSD a printcap entry can be no larger than 1024 characters
* and comments must sit on lines by themselves.
*
* Parameters:
* fptr (I) - pointer to an open printcap file.
*
* Return: Pointer to the next entry in the file or NULL if no more
* entries can be found.
*
**************************************************************************/
static char *get_entry(FILE *fptr)
{
static char entry[SL_BUF_PRINTCAP];
char buf[SL_SML_BUFSIZ], *bptr, *cptr;
char *eptr = NULL;
/*
* Look for an entry
*/
*entry = '\0';
while (fgets(buf, SL_SML_BUFSIZ, fptr) != NULL) {
if (*buf == '\n' || strchr(buf, '#'))
continue;
buf[strlen(buf) - 1] = '\0';
if ((bptr = _SLSkipSpace(buf)) == NULL)
continue;
eptr = strcat(entry, bptr);
if ((cptr = strrchr(entry, '\\')) == NULL)
break;
*cptr = '\0';
}
return eptr;
}
/**************************************************************************
*
* Function: parse_capabilities
*
* Description: Parses the specified printcap entry for the capabilities
* relevant to the printer structure. The name fields in the entry
* are not parsed. All fields in printer structure are initialized.
*
* This routine assumes that entries that match our keywords will
* appear as keyword=value with no leading whitespace, no whitespace
* between the keyword, '=', or value.
*
* Parameters:
* eptr (I) - pointer to a printcap entry
* printer (I) - printer structure to fill
*
* Return: none
*
**************************************************************************/
static void parse_capabilities(char *eptr, SLPrinterStruct *printer)
{
char entry[SL_BUF_PRINTCAP], *sptr;
char *vptr, *loc;
int i;
/*
* Initialize the printer struct
*/
printer->local_name = NULL;
printer->formal_name = NULL;
printer->type = NULL;
printer->dev = NULL;
printer->is_def = 0;
printer->is_networked = 0;
printer->remote_host = NULL;
printer->remote_name = NULL;
printer->network_type = NULL;
/*
* Initialize keyword structure
*/
keywords[0].pvar = &printer->dev;
keywords[1].pvar = &printer->type;
keywords[2].pvar = &printer->remote_host;
keywords[3].pvar = &printer->remote_name;
(void)strcpy(entry, eptr);
(void)strtok_r(entry, ":", &loc);
while ((sptr = strtok_r(NULL, ":", &loc)) != NULL) {
/*
* Search the keyword list
*/
for (i = 0; i < num_keywords; i++) {
if (!strncmp(sptr, keywords[i].key, 2)) {
vptr = sptr + 3;
if (*vptr)
*keywords[i].pvar = strdup(vptr);
break;
}
}
}
/*
* If the remmote_host field has been filled, then
* the printer is networked
*/
if (printer->remote_host) {
printer->is_networked = 1;
printer->network_type = strdup("bsd");
}
/*
* If the type field did not get filled mark it Unknown
*/
if (!printer->type)
printer->type = strdup("Unknown");
}
/**************************************************************************
*
* Function: def_check
*
* Description: Checks for the presence of the specified printer name on
* a printercap name line.
*
* Parameters:
* nptr (I) - printer name section of a printcap entry. Trailing ':'
* has been removed.
* def (I) - default printer name.
*
* Return: 0 if 'lp' not found. 1 if found.
*
**************************************************************************/
static int def_check(char *nptr, char *def)
{
char buf[SL_SML_BUFSIZ];
char *sptr, *loc;
if (strstr(nptr, def) == NULL)
return 0;
(void)strcpy(buf, nptr);
sptr = buf;
while ((sptr = strtok_r(sptr, "|", &loc)) != NULL) {
if (strcmp(sptr, def))
return 1;
sptr = NULL;
}
return 0;
}
/**************************************************************************
*
* Function: parse_queue
*
* Description: Parses an lpq queue output string and places the
* appropriate info in the specified queue structure.
*
* Parameters:
* entry (O) - queue structure to be filled
* line (I) - lpq output line to parse
*
* Return: none
*
**************************************************************************/
static void parse_queue(SLQueueStruct *entry, char *line)
{
char job_id[SL_SML_BUFSIZ], owner[SL_SML_BUFSIZ];
char *sptr;
/*
* Initialize all fields in case not everything gets filled
*/
entry->job_id = entry->username = NULL;
entry->size = entry->time_stamp = 0;
entry->title = NULL;
/*
* Init buffers in case not scanned
*/
*job_id = *owner = '\0';
/*
* Parse the line
*/
(void)sscanf(line, "%*s %s %s", owner, job_id);
if (*job_id)
entry->job_id = strdup(job_id);
if (*owner)
entry->username = strdup(owner);
if ((sptr = strstr(line, "byte")) != NULL) {
for (sptr -= 2; isdigit(*sptr); sptr--)
;
entry->size = atoi(++sptr);
}
}